package com.cmwa.scbp.sys.menu.aop;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import com.cmwa.scbp.base.mvc.entity.Page;
import com.cmwa.scbp.sys.menu.entity.BtnAuthVo;
import com.cmwa.scbp.sys.permission.authority.dao.AuthorityDao;
import com.cmwa.scbp.sys.permission.authority.entity.AuthorityVo;
import com.cmwa.scbp.utils.SessionUtils;


/**
 * 根据人+资源查找所拥有的操作权限
 * 用于前端判断是否显示操作按钮
 * @author ex-zuotc 2018年6月12日
 */
@Aspect
public class RequestPermissionListAspect {

	private static Logger log = LoggerFactory.getLogger(RequestPermissionListAspect.class);
	
	@Resource
	private AuthorityDao authorityDao;
	
	/**
	 * 分页方法执行完毕后，查询对应操作人在对应资源上的操作权限
	 * @param joinPoint
	 * @param pageList
	 * @throws Exception
	 */
	@AfterReturning(pointcut = "within(com.cmwa..service..*) && @annotation(com.cmwa.scbp.sys.menu.aop.RequestPermissionList)", returning = "pageList")
	public void requestPermission(JoinPoint joinPoint, Object pageList) throws Exception {
		
		// 当前用户
		String empId = SessionUtils.getEmployee().getID();
		// 注解
		MethodSignature ms = (MethodSignature) joinPoint.getSignature();
		RequestPermissionList requestPermissionList = ms.getMethod().getAnnotation(RequestPermissionList.class);
		if (requestPermissionList != null) {
			// 权限层级
			ResourceTypeEnum resourceType = requestPermissionList.ResourceType();
			// 请求的资源取值表达式
			String resourceSpel = requestPermissionList.resourceSpel();
			
			String[] otherBtnIds = requestPermissionList.otherBtnIds();
			
			Page<?> returnPage = null;
			if (pageList instanceof Page) {
				returnPage = (Page<?>) pageList;
			}
	
			// 分页返回的资源id
			List<String> resourceIds = new ArrayList<String>();
			List<?> resultList = null;
			if (returnPage != null) {
				resultList = returnPage.getItems();
				if (resultList != null && resultList.size() > 0) {
	
					// spel 上下文
					EvaluationContext context = new StandardEvaluationContext();
					// 创建SPEL解析器
					ExpressionParser parser = new SpelExpressionParser();
					Expression el = parser.parseExpression("#item." + resourceSpel);
					// 获取分页对象中所有资源的ID
					for (Object obj : resultList) {
						context.setVariable("item", obj);
						String resourceId = el.getValue(context, String.class);
						resourceIds.add(resourceId);
					}
					
					if (StringUtils.isNotEmpty(empId) && CollectionUtils.isNotEmpty(resourceIds)) {
						BtnAuthVo btnAuthVo = new BtnAuthVo();
						btnAuthVo.setEmpId(empId);
						btnAuthVo.setResourceIds(resourceIds);
						btnAuthVo.setType(resourceType.toString());
						btnAuthVo.setMenuId(returnPage.getMenuId());
						btnAuthVo.setOtherBtnIds(otherBtnIds);
						
						// 查询用户在资源上的可操作权限
						Map<String, Map<String, String>> permissionResult = new HashMap<String, Map<String, String>>();
						log.error("===== 开始查询当前人员对应的操作权限 =====");
						long start = System.currentTimeMillis();
						// 根据人员 + ids + 层级查询所有的按钮代码集合
						List<AuthorityVo> authorityList = new ArrayList<AuthorityVo>();
						long end = System.currentTimeMillis();
						log.error("===== 查询当前人员对应的操作权限结束, 耗时：" + (end - start) + "ms =====");
						// 循环分页对象的id集合
						for (String id : resourceIds) {
							Map<String, String> btnMap = new HashMap<String, String>();
							// 循环按钮代码集合，根据资源id组装map
							for (AuthorityVo authorityVo : authorityList) {
								String queryId = authorityVo.getResourceId();
								// 如果查询出来的按钮对应的资源id和分页对象的id相同
								if (StringUtils.equals(queryId, id)) {
									btnMap.put(authorityVo.getMcode(), authorityVo.getMcode());
								}
							}
							permissionResult.put(id, btnMap);
						}
						returnPage.setPermissionResult(permissionResult);
					}
				}
			}
		}
		
	}

}
